home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 November: Tool Chest / Dev.CD Nov 98 TC.toast / Tool Chest / QuickDraw / Virtual Sphere 1.0.1 / Virtual Sphere Sample Code 1.1 / Offscreen.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-25  |  7.0 KB  |  201 lines  |  [TEXT/MPS ]

  1. /*•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
  2. /* Offscreen.c
  3. /*
  4. /* Yet another offscreen drawing module that uses GWorld to eliminate drawing flicker.
  5. /*
  6. /* Author: Michael Chen, Human Interface Group / ATG
  7. /* Copyright © 1991-1993 Apple Computer, Inc.  All rights reserved.
  8. /*
  9. /* Part of Virtual Sphere Sample Code Release v1.1
  10. /*•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••*/
  11.  
  12. #ifndef __OFFSCREEN__
  13. #include "Offscreen.h"
  14. #endif
  15.  
  16. #ifndef __QDOFFSCREEN__
  17. #include <QDOffscreen.h>
  18. #endif
  19.  
  20. #ifndef __GESTALTEQU__
  21. #include <GestaltEqu.h>
  22. #endif
  23.  
  24. #ifndef __MEMORY__
  25. #include <Memory.h>
  26. #endif
  27.  
  28. #ifndef __ERRORS__
  29. #include <Errors.h>
  30. #endif
  31.  
  32. /* Local globals for this file (module) only */
  33. static    CGrafPtr    lgSavedPort            = nil;
  34. static    GDHandle    lgSavedGDH            = nil;
  35. static    Boolean        lgRunningSystem7    = false;
  36.  
  37. /*=================================================================================================
  38. /* InitializeOffscreen
  39. /*
  40. /* Must be called before any other routines in this module.
  41. /* Check for availibility of GWorld.  GWorld exists if we are running
  42. /* System 7 or if 32-bit QuickDraw is installed.
  43. /*-------------------------------------------------------------------------------------------------*/
  44. pascal OSErr InitializeOffscreen (Boolean *gWorldAvailable)
  45. {
  46.     OSErr    err;
  47.     long    gestaltResponse;
  48.     
  49.     *gWorldAvailable = false;
  50.     
  51.     /* Check for System 7 */
  52.     err = Gestalt (gestaltSystemVersion, &gestaltResponse);
  53.     if (err != noErr) return (err);
  54.     lgRunningSystem7 = (gestaltResponse & 0xF00) == 0x700;
  55.     if (lgRunningSystem7) {
  56.         /* We are happy */
  57.         *gWorldAvailable = true;
  58.         return (noErr);
  59.     }
  60.  
  61.     /* Running System 6.  Check for 32-bit Quickdraw */
  62.     err = Gestalt (gestaltQuickdrawVersion, &gestaltResponse);
  63.     if (err != noErr) return (err);
  64.     if (gestaltResponse & gestalt32BitQD) *gWorldAvailable = true;
  65.     return (noErr);
  66. }
  67.  
  68. /*=================================================================================================
  69. /* FreeOffscreen
  70. /*
  71. /* Free the offscreen GWorld.
  72. /*-------------------------------------------------------------------------------------------------*/
  73. pascal void FreeOffscreen (GWorldPtr offscreenGWorld)
  74. {
  75.     if (offscreenGWorld != nil) DisposeGWorld (offscreenGWorld);
  76. }
  77.  
  78. /*=================================================================================================
  79. /* CheckOffscreen
  80. /*
  81. /* Check if a new GWorld needs to be reallocated because the window has been moved
  82. /* or bit-depth has been changed.  Routine will also allocate a new GWorld if the
  83. /* variable offscreenGWorld doesn't have one yet (i.e. offscreenGWorld is nil).
  84. /* If a GWorld cannot be made, offscreenGWorld is set to nil.
  85. /*
  86. /* Call this routine any time to make sure offscreenGWorld has the right configuration.
  87. /*-------------------------------------------------------------------------------------------------*/
  88. pascal QDErr CheckOffscreenForWindow (GWorldPtr *offscreenGWorld,
  89.                                         short        pixelDepth,
  90.                                         WindowPtr window)
  91. {    
  92.     Rect        boundsRect;
  93.     QDErr        err;
  94.     GWorldFlags newFlags;
  95.     
  96.     boundsRect = window->portRect;
  97.  
  98.     if (pixelDepth == 0) {
  99.         /* boundsRect has to be in global coordinate (IM6 p. 21-13) */
  100.         GrafPtr savedPort;
  101.         GetPort (&savedPort);
  102.         SetPort (window);
  103.         LocalToGlobalRect (&boundsRect);
  104.         SetPort (savedPort);
  105.     }
  106.     
  107.     if (*offscreenGWorld == nil) {
  108.         /* No GWorld yet.  Allocate a new one */
  109.         err = NewGWorld (offscreenGWorld, pixelDepth, &boundsRect,
  110.                          (CTabHandle) nil, (GDHandle) nil, (GWorldFlags) 0);
  111.         return (err);
  112.     } else {
  113.         /* There is an existing GWorld */
  114.         
  115.         #if qDebug
  116.         GWorldPtr oldGWorld = *offscreenGWorld;
  117.         #endif
  118.         
  119.         /* Check if offscreen GWorld needs to be reallocated */
  120.         newFlags = UpdateGWorld (offscreenGWorld, pixelDepth, &boundsRect,
  121.                                 (CTabHandle) nil, (GDHandle) nil, (GWorldFlags) 0);
  122.         if (newFlags & (1L<<gwFlagErrBit)) return ((long) newFlags);
  123.  
  124.         #if qDebug
  125.         if (StripAddress (oldGWorld) != StripAddress(*offscreenGWorld)) MessageAlert ("\pNew GWorld was reallocated");
  126.         #endif
  127.         
  128.         return ((*offscreenGWorld == nil) ? memFullErr : noErr);
  129.     }
  130. }
  131.  
  132. /*=================================================================================================
  133. /* BeginDrawingOffscreen
  134. /*
  135. /* Call this to redirect drawings to an offscreen GWorld.  Finish redirection
  136. /* by calling EndDrawingOffscreen.
  137. /* Note the different ways of accessing the pixMap of a GWorld depending on
  138. /* whether System 6 or 7 is running.  Read IM6 p. 21-19 very carefully!
  139. /* Note also that GetGWorldPixMap() could return a bitMap instead of a pixMap
  140. /* behind your back (e.g. on a PowerBook 100).
  141. /*-------------------------------------------------------------------------------------------------*/
  142. pascal void BeginDrawingOffscreen (GWorldPtr offscreenGWorld, WindowPtr window)
  143. {
  144.     #pragma unused(window)        /* Suppresses warning in MPW since THINK C requires "window" to be named */
  145.     
  146.     if (offscreenGWorld != nil) {
  147.         GetGWorld (&lgSavedPort, &lgSavedGDH);
  148.  
  149.         /* lock the offscreen pixels down! */
  150.         if (lgRunningSystem7) {
  151.             /* Note getting the offScreenPixMap the proper way */
  152.             if (!LockPixels (GetGWorldPixMap (offscreenGWorld))) {
  153.                 DebugMessage ("\pBeginDrawingOffscreen: LockPixels failed");
  154.             }
  155.         } else {
  156.             /* Note getting the offScreenPixMap by dereferencing offscreenGWorld.  Not as
  157.              * clean but GetGWorldPixMap is not available in Sys 6. */
  158.             if (!LockPixels (offscreenGWorld->portPixMap)) {
  159.                 DebugMessage ("\pBeginDrawingOffscreen: LockPixels failed");
  160.             }
  161.         }
  162.         
  163.         /* Redirect drawings offscreen only if pixels are locked down */
  164.         SetGWorld (offscreenGWorld, (GDHandle) nil);
  165.     }
  166. }
  167.  
  168. /*=================================================================================================
  169. /* EndDrawingOffscreen
  170. /*
  171. /* End redirecting drawing to an offscreen GWorld and copy the GWorld to the window.
  172. /*-------------------------------------------------------------------------------------------------*/
  173. pascal void EndDrawingOffscreen (GWorldPtr offscreenGWorld, WindowPtr window)
  174. {
  175.     if (offscreenGWorld != nil) {
  176.         /* End redirection of drawings to offscreenGWorld */
  177.         SetGWorld (lgSavedPort, lgSavedGDH);
  178.         
  179.         /* Make sure CopyBits is happy.
  180.          * Specifically, if foreColor and bkColor are not (0,0,0) and (0xffff, 0xffff, 0xffff)
  181.          * CopyBits will "colorize" instead of doing a straight copy. */
  182.         ForeColor (blackColor);
  183.         BackColor (whiteColor);
  184.  
  185.         if (lgRunningSystem7) {
  186.             /* Get the offScreenPixMap the proper way */
  187.             PixMapHandle offScreenPixMap = GetGWorldPixMap (offscreenGWorld);
  188.             /* Note pixMap should still be locked */
  189.             CopyBits ((BitMap *) *offScreenPixMap, &window->portBits,
  190.                       &offscreenGWorld->portRect, &window->portRect, srcCopy, nil);
  191.             UnlockPixels (offScreenPixMap);
  192.         } else {
  193.             /* Get the offScreenPixMap by dereferencing offscreenGWorld.  Not as
  194.              * clean but GetGWorldPixMap is not available in Sys 6 */
  195.             CopyBits (&((GrafPtr) offscreenGWorld)->portBits, &window->portBits,
  196.                       &offscreenGWorld->portRect, &window->portRect, srcCopy, nil);
  197.             UnlockPixels (offscreenGWorld->portPixMap);
  198.         }
  199.     }
  200. }
  201.